#pragma once

#include "nfa.hpp"
#include <string>
#include <vector>
#include <unordered_set>
#include <algorithm>

namespace dfa
{
    class Dfa
    {
    public:
        static Dfa* getDfaFromNfaSet(const std::unordered_set<nfa::Nfa*>& input)
        {
            Dfa* dfa = new Dfa();
            for (const auto& e : input) {
                dfa->_nfa_states.insert(e);
                if (!e->_next1 && !e->_next2) dfa->_accepted = true;
            }
            dfa->_state_num = STATE_NUM++;
            return dfa;
        }

        std::unordered_set<nfa::Nfa*> getNfaStates()
        { return _nfa_states; }

        std::string showNfaStates()
        {
            std::string res;
            for (const auto& e : _nfa_states) {
                res += std::to_string(e->getNum());
                res += ' ';
            }
            return res;
        }

        static void dfaFree(Dfa* dfa)
        {
            --STATE_NUM;
            delete dfa;
        }

        int getStateNum()
        { return _state_num; }

        auto getAccepted()
        { return _accepted; }

    private:
        Dfa ():_state_num(0), _accepted(false) {}

        static size_t STATE_NUM;
        size_t _state_num;
        bool _accepted;
        std::unordered_set<nfa::Nfa*> _nfa_states;
    };
    size_t Dfa::STATE_NUM = 0;
}

